10 d1 = .5:d2 = 3.5:s = .05 'calibration distances   
20 GOSUB 880 'reset lcd display
30 first = 0
40 SETPIN 11,5 'count pin
50 SETPIN 8,1:SETPIN 7,1  'adc pins
60 SETPIN 14,2 'digital input pin
70 PIN(10) = 1
80 SETPIN 10,8 'pin 10 pulses TX HIGH = Off
90 IF PIN(7) > 1 THEN GOSUB 490 'is calibration needed?
100 OPEN "coeff.txt" FOR input AS #1 'read calibration data
110 INPUT #1,alpha,beta:CLOSE #1 
120 REM *************start of loop
130    IF PIN(7) > 1 THEN GOSUB 490
140    flag = 0
150    SOUND 200000,5000
160    SETPIN 9,7,450      'interrupt pin
170    SETPIN 11,5 'start counter pin 11
180    PIN(10) = 0'send pulse
190    PIN(10) = 0 'keep sending
200    PIN(10) = 1 'stop pulse
210    PAUSE 1000 'wait for echo
220    IF flag = 0 THEN 'have not gone to interrupt- out of range
230    l1$ = "out of range":l2$ = " ":data = 1:GOSUB 1110
240    GOSUB 990:GOTO 130
250    ENDIF
260    volt = 0 'average thermistor voltage
270    FOR i = 1 TO 100:volt = volt + PIN(8):NEXT i:volt = volt/100
280    rt = (330/volt - 100)*1000 'calculate thermistor resistance
290    temp = 4500/LOG(rt/.02787) 'calculate temperature
300    v = 331.3*SQR(temp/273.15) 'calculate velocity of sound
310    m = v *2.5/1000000 'calculate gradient
320    IF NOT first THEN first = 1:GOTO 400 'discard first reading
330    dist = alpha*m*count + beta 'calculate distance
340    dist = SQR(dist^2 - (s^2)/4) 'distance corrected for parallax
350    dist = (INT(100*dist + .5))/100 'display to nearest cm
360    data = 1:GOSUB 1110 'clear display
370    l1$ = STR$(dist) + " m" 'display result
380    l2$ = STR$(count)
390    GOSUB 990
400    PAUSE 2000 '2 seconds to observe result
410 GOTO 130 'do it all again
420 END
430 REM**************end loop
440 REM**************start interrupt
450 count = PIN(11)    'get pulse count
460 SETPIN 9,0 'disable interrupt
470 flag = 1 'flag a received echo
480 IRETURN
490 REM *************start of calibration
500 volt = 0 'average the thermistor voltage
510 FOR i = 1 TO 100:volt = volt + PIN(8):NEXT i:volt = volt/100
520 rt = (330/volt - 100)*1000 'calculate thermistor resistance
530 temp = 4500/LOG(rt/.02787) 'calculate temperature
540 v = 331.3*SQR(temp/273.15) 'calculate velocity of sound
550 m = v *2.5/1000000 'calculate gradient
560 IF PIN(14) = 1 THEN
570   l1$ = "make selection":l2$ = "then push switch"
580   GOSUB 990:GOTO 560 'wait til switch is pressed
590 ENDIF
600 data = 1:GOSUB 1110 'clear display
610 IF PIN(7) < 1.1 THEN GOTO 840 'calibration finished-save & exit to main routine
620 c = 0
630 FOR j = 0 TO 100 'get 100 measures of count
640   flag = 0
650   SOUND 200000,5000
660   SETPIN 9,7,450     'interrupt pin
670   SETPIN 11,5 'start counter pin 11
680   PIN(10) = 0'send pulse
685 PIN(10) = 0
690   PIN(10) = 1 'stop pulse
700   PAUSE 1000 'wait for return pulse
710   IF flag = 0 THEN 650 'no return pulse - try again
720   IF NOT j THEN 760 'discard first reading
730   l1$ = STR$(j)
740   l2$ = STR$(count):GOSUB 990
750   c = c + count
760 NEXT j
770 IF PIN(7) > 2.2 THEN
780    c1 = c/100:GOTO 560
790 ELSEIF PIN(7) > 1.1 THEN
800    c2 = c/100:GOTO 560
810 ELSE GOTO 840
820 ENDIF
830 REM exit routine
840 alpha = (d1 - d2)/m/(c1 - c2):beta = (c1*d2 - c2*d1)/(c1 - c2)
850 OPEN "coeff.txt" FOR output AS #2
860 WRITE #2,alpha,beta:CLOSE #2
870 RETURN
880 'INITIALISATION SUBROUTINE''''''''''''''''''''''''''''''''''''''
890 FOR i = 15 TO 20:SETPIN i,9:NEXT i:PIN(16) = 0 'set pins oc
900 data = 3:GOSUB 1170:PAUSE 5'reset
910 data = 3:GOSUB 1170:PAUSE 5'reset
920 data = 3:GOSUB 1170:PAUSE 5'reset
930 data = 2:GOSUB 1170:PAUSE 5'set 4 bit mode
940 data = &B00101000:GOSUB 1110'set 4 bit,2lines,5x7 display
950 data = &B00001100:GOSUB 1110'set display on,no cursor
960 data = &B00000110:GOSUB 1110'set increment on write
970 data = &B00000001:GOSUB 1110'clear display
980 RETURN
990 'SEND CHARACTERS IN l1$ & l2& to LCD'''''''''''''''''''''''''''''''''''''
1000 data = &H80:PIN(16) = 0:GOSUB 1110'set cursor to beginning of line 1
1010 FOR byte = 1 TO LEN(l1$)'send characters
1020   data = ASC(MID$(l1$,byte,1))
1030   PIN(16) = 1:GOSUB 1110
1040 NEXT byte
1050 data = &B11000000:PIN(16) = 0:GOSUB 1110'set cursor to beginning of line 2
1060 FOR byte = 1 TO LEN(l2$)'send characters
1070   data = ASC(MID$(l2$,byte,1))
1080   PIN(16) = 1:GOSUB 1110
1090 NEXT byte
1100 RETURN
1110 'SEND A BYTE TO LCD IN 2 NIBBLES. UPPER NIBBLE 1ST''''''''''''''''''''''''''''''''''''''
1120 PIN(20) = data AND 16
1130 PIN(18) = data AND 32
1140 PIN(19) = data AND 64
1150 PIN(17) = data AND 128
1160 PIN(15) = 1:PAUSE 10:PIN(15) = 0
1170 'ENTRY POINT TO SEND JUST 4 BITS TO LCD. ALSO SENDS LOWER NIBBLE''''''''''''''''''''''''''''''''''''''
1180 PIN(20) = data AND 1
1190 PIN(18) = data AND 2
1200 PIN(19) = data AND 4
1210 PIN(17) = data AND 8
1220 PIN(15) = 1:PAUSE 10:PIN(15) = 0:PIN(16) = 0
1230 RETURN
              
              

